package cn.ibizlab.odoo.util.valuerule.aop;

import cn.ibizlab.odoo.util.helper.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.validation.Validator;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 自定义值规则开启注解@EnableValueRule 解析器（AOP)
 *
 */
@Slf4j
@Aspect
@Component
public class ValueRoleAnnoAspect {

    @Pointcut("@annotation(cn.ibizlab.odoo.util.valuerule.aop.EnableValueRule)")
    public void pointCut() {
    }

    @Before("pointCut() && @annotation(vrAnno) ")
    public void validateVR(JoinPoint joinPoint, EnableValueRule vrAnno) throws Exception {
        //flag=false时，不验证。
        if(vrAnno.flag()==false){
            return;
        }

        Object[] args = joinPoint.getArgs();
        if(args==null|| !(args.length==1)){
            throw new RuntimeException("当前版本支持pojo参数值规则校验。");
        }
        Object pojo = args[0];

        String pojoName = pojo.getClass().getSimpleName();
        Field[] fields = pojo.getClass().getDeclaredFields();
        BindException errors = new BindException(pojo, pojoName);

        for (Field field : fields) {
            Annotation[] annotations = field.getAnnotations();
            for (Annotation annotation : annotations) {
                String annoPackageName = annotation.annotationType().getPackage().getName();
                String annoName = annotation.annotationType().getSimpleName();

                //只对值规则校验注解，进行解析校验。
                if (annoPackageName.contains("valuerule.anno")) {
                    Method method = pojo.getClass().getMethod("get" + capFirst(field.getName()));
                    Object fieldValue = method.invoke(pojo);

                    Validator validator = SpringContextHolder.getBean(annoName + "Validator");
                    validator.validate(fieldValue, errors);
                }
            }
        }

        log.info("【"+pojoName+"】值规则校验结果:"+errors.getMessage());
        if(errors.hasErrors()){
            throw errors;
        }
    }

    private static String capFirst(String s) {
        char firstChar =Character.toUpperCase(s.charAt(0));
        return firstChar+s.substring(1);
    }

}
